package main

import (
	"fmt"
)

/**
单向链表节点
*/
type SingleNode struct {
	no   int         //编号
	data interface{} //数据域
	//prev *SingleNode //prev指针域
	next *SingleNode //next指针域
}

/**
初始化新的结点
*/
func NewSingleNode(value interface{}, no int) *SingleNode {
	node := new(SingleNode)
	node.data = value
	node.no = no
	return node
}

/*
带head头节点的作用就是表示单链表的头
他有个next域，指向下一个节点
*/

/**
添加节点
思路：
1.找到当前链表的最后节点
2.将最后这个节点的next域指向 新节点
*/
func Add(head *SingleNode, node *SingleNode) {
	//因为头head节点不能动，因此需要一个辅助变量去变量整个链表
	//然后找到最后的那个节点

	//这一步是将头节点指向给一个临时变量，因为遍历整个链表是从头节点开始的
	temp := head
	//循环
	for true {
		if temp.next == nil {
			//找到了当前链表的最后那个节点了
			break
		} else {
			//将temp中的下一个节点，指向给临时变量temp
			temp = temp.next
		}
	}
	//说明已经找到，这儿需要注意哈，找到的最后这个节点是指向temp
	//而不是temp.next这一点至关重要，一定要整清楚，不清楚就看图
	//因为temp是最后那个节点，所以把他的next域指向给新添加的节点
	temp.next = node
}

/**
添加节点
根据no编号，编号从下到大的顺序插入
*/
func AddByNo(head *SingleNode, node *SingleNode) {

	/*******************代码****************************/
	temp := head
	for true {
		//判断当 temp是否已经是 最后那个节点了
		if temp.next != nil {
			//temp的下一个节点的编号
			nextno := temp.next.no
			//如果temp的next节点的no大于 要新插入的节点的编号
			//说明这个节点 就可以插入在 temp的后面
			if nextno >= node.no {
				//先保存原有的temp.next
				//next := temp.next
				////修改temp.next的指向，指向新插入的节点
				//temp.next = node
				////修改新节点的指向，指向
				//node.next = next

				//必须开辟一个空间去存
				node.next = temp.next
				temp.next = node

				break
			} else {
				//继续移动
				temp = temp.next
			}
		} else {
			//temp已经是最后那个节点了，这种情况下就直接将新的节点插入
			temp.next = node
			break
		}
	}
}

/**
根据编号no删除,指定节点
*/
func DeleteByNo(head *SingleNode, no int) {
	temp := head
	/*

	 */
	for true {
		if temp.next != nil {
			nextno := temp.next.no
			//找到要删除的那个节点
			if nextno == no {
				//temp.next 就是要删除的那个节点
				if temp.next.next != nil {
					temp.next = temp.next.next
				} else {
					//删除到最后一个节点了
					temp.next = nil
				}
				break
			} else {
				temp = temp.next
			}
		} else {
			break
		}
	}
}

/**
显示当前链表
*/
func ShowNode(head *SingleNode) {
	temp := head
	if temp.next == nil {
		fmt.Println("当前链表为空!")
		return
	}
	for true {
		fmt.Printf("节点_data:%v,no:%d\n", temp.data, temp.no)

		//temp = temp.next
		//if temp.next == nil {
		//	break
		//}
		if temp.next != nil {
			temp = temp.next
		} else {
			break
		}
	}

}

/**
单链表
*/
func main() {
	//1.先创建一个头节点
	head := new(SingleNode)
	newnode3 := NewSingleNode("4号", 4)

	//添加节点
	AddByNo(head, newnode3)

	//2.创建一个新的节点
	newnode := NewSingleNode("1号", 1)
	//添加节点
	AddByNo(head, newnode)

	newnode1 := NewSingleNode("2号", 2)
	//添加节点
	AddByNo(head, newnode1)

	newnode2 := NewSingleNode("3号", 3)
	//添加节点
	AddByNo(head, newnode2)

	ShowNode(head)

	DeleteByNo(head, 1)
	DeleteByNo(head, 2)
	DeleteByNo(head, 3)
	DeleteByNo(head, 4)

	ShowNode(head)
}
